package com.chuangjiangx.member.coupon.ddd.domain.model;

import com.chuangjiangx.commons.exception.BaseException;
import com.chuangjiangx.dddbase.Entity;
import com.chuangjiangx.dddbase.domain.shared.Timestamp;

import com.chuangjiangx.member.coupon.ddd.domain.model.*;
import com.chuangjiangx.member.stored.ddd.domain.MbrRandomUtils;
import com.chuangjiangx.member.basic.ddd.domain.model.MemberId;
import com.chuangjiangx.member.basic.ddd.domain.model.StoreId;
import com.chuangjiangx.member.basic.ddd.domain.model.StoreUserId;
import lombok.AllArgsConstructor;
import lombok.Getter;

import java.util.Date;

@Getter
@AllArgsConstructor
public class MbrHasCoupon extends Entity<MbrHasCouponId>{
    private MemberId memberId; //会员id
    private MbrCouponId mbrCouponId; //卡券id
    private VerifyStatus verifyStatus; //核销状态
    private Date claimTime; //领取时间

    private StoreId verifyStoreId; //核销门店id
    private StoreUserId verifyStoreUserId; //核销店员id
    private Date verifyTime; //核销时间
    private VerifyTerminal verifyTerminal; //核销终端
    private String verifyCode; //核销码
    /**
     * 卡券使用时间/核销时间
     */
    private Date useTime;

    private WxVerifyStatus wxVerifyStatus;
    private WxSyncStatus wxSyncStatus;

    /**
     * 会员领取卡券
     * @param memberId
     * @param mbrCouponId
     */
    public MbrHasCoupon(MemberId memberId,MbrCouponId mbrCouponId) {
        this.memberId = memberId;
        this.mbrCouponId = mbrCouponId;
        this.verifyStatus = VerifyStatus.UNUSED;
        this.claimTime = new Date();
        this.verifyCode = generateVerifyCode();
        this.setTimestamp(new Timestamp(new Date(),new Date()));
    }

    /**
     * 卡券过期
     */
    public void overdueVerifyStatus() {
        this.verifyStatus = VerifyStatus.OVERDUE;
        this.update();
    }

    /**
     * 卡券校验记录
     */
    public void verifyRecord(Long storeId, Long storeUserId) {
        if (storeId != null) {
            this.verifyStoreId = new StoreId(storeId);
        }
        if (storeUserId != null) {
            this.verifyStoreUserId = new StoreUserId(storeUserId);
        }
        this.verifyTime = new Date();
        this.update();
    }

    /**
     * 支付成功后确认核销
     */
    public void use() {
        this.verifyStatus = VerifyStatus.USED;
        this.useTime = new Date();
        this.update();
    }

    /**
     * 卡券进入冻结
     * @return
     */
    public boolean lock() {
        switch (this.verifyStatus){
            case FROZEN:
                // 已冻结
                throw new BaseException("","该卡券已被冻结,请一分钟后重试");
            case UNUSED:
                // 未使用
                this.verifyStatus = VerifyStatus.FROZEN;
                this.update();
                return true;
            case USED:
                // 已使用
                throw new BaseException("","该卡券已经被使用");
            case OVERDUE:
                // 已过期
                throw new BaseException("","该卡券已过期");
            default:
                throw new UnsupportedOperationException("不支持的卡券状态");
        }
    }

    public boolean unlock() {
        if (VerifyStatus.FROZEN.equals(this.verifyStatus)) {
            this.verifyStatus = VerifyStatus.UNUSED;
            this.update();
            return true;
        }
        return false;
    }

    public void wxUnavaliable(){
        this.wxVerifyStatus = WxVerifyStatus.INVALID;
        this.update();
    }

    public void wxVerified(){
        this.wxVerifyStatus = WxVerifyStatus.VERIFIED;
        this.update();
    }

    public void wxSynced(){
        this.wxSyncStatus = WxSyncStatus.SYNCED;
        this.update();
    }

    /**
     * 生成核销码
     */
    @SuppressWarnings("Duplicates")
    private String generateVerifyCode() {
        return MbrRandomUtils.generateMbrCouponVerifyCode();
    }

}
